package com.yuju.account.service.impl;


import java.math.BigDecimal;
import java.util.*;

import com.sun.org.apache.bcel.internal.generic.NEW;
import com.yuju.account.enums.*;
import com.yuju.account.model.ShiftAccountModel;
import com.yuju.account.model.ShiftEmpModel;
import com.yuju.account.service.IAccountService;
import com.yuju.account.service.IShiftEmpService;
import com.yuju.cache.RedisCache;
import com.yuju.constant.CacheKey;
import com.yuju.enums.StatusEnum;
import com.yuju.exception.BusinessException;
import com.yuju.group.service.ICodeGenService;
import com.yuju.model.account.AccountModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yuju.account.dao.IShiftDao;
import com.yuju.account.dao.entity.Shift;
import com.yuju.account.model.ShiftModel;
import com.yuju.account.service.IShiftService;
import com.yuju.common.core.dao.IBaseDao;
import com.yuju.common.core.service.AbstractBaseService;
import com.yuju.util.Utils;

@Service
public class ShiftServiceImpl extends AbstractBaseService<ShiftModel, Shift, String> implements IShiftService {
	
	@Autowired
	private IShiftDao shiftDao;

	@Autowired
	private IAccountService accountService;

	@Autowired
	private IShiftEmpService shiftEmpService;

	@Autowired
	private ICodeGenService codeGenService;

	private static RedisCache simpleCache = RedisCache.getInstance();

	private void updateShiftOperatorEmp(List<ShiftEmpModel> list, AccountModel accountModel) {
		if (list == null || accountModel == null) {
			return;
		}

        Byte payMethod = accountModel.getBusinessTypeDetail();
        if (!(payMethod.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_XJ.getValue())
                || payMethod.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_SK.getValue())
                || payMethod.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_ZZ.getValue())
                || payMethod.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_WX.getValue())
                || payMethod.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_ZFB.getValue()))){
		    return;
        }

		Boolean isNewEmp = true;
		ShiftEmpModel shiftEmpModel = new ShiftEmpModel();
		for (ShiftEmpModel item:list) {
			if (item.getEmpId().equals(accountModel.getCreateUserId())) {
				isNewEmp = false;
				shiftEmpModel = item;
				break;
			}

		}

		if (isNewEmp) {
			shiftEmpModel.setClassId(accountModel.getClassId());
			shiftEmpModel.setHotelId(accountModel.getHotelId());
			shiftEmpModel.setGroupId(accountModel.getGroupId());
			shiftEmpModel.setEmpId(accountModel.getCreateUserId());
			shiftEmpModel.setOperatorName(accountModel.getCreateUserName());
		}

        if (payMethod.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_XJ.getValue())) {
			BigDecimal sum = shiftEmpModel.getSsCashSum();
			shiftEmpModel.setSsCashSum(sum.add(accountModel.getMoney()));
		}
		else if (payMethod.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_ZZ.getValue())
				|| payMethod.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_SK.getValue())) {
			BigDecimal sum = shiftEmpModel.getSsBankSum();
			shiftEmpModel.setSsBankSum(sum.add(accountModel.getMoney()));
		}
		else if (payMethod.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_WX.getValue())) {
			BigDecimal sum = shiftEmpModel.getSsWxSum();
			shiftEmpModel.setSsWxSum(sum.add(accountModel.getMoney()));
		}
		else if (payMethod.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_ZFB.getValue())) {
			BigDecimal sum = shiftEmpModel.getSsZfbSum();
			shiftEmpModel.setSsZfbSum(sum.add(accountModel.getMoney()));
		}


	}

	@Override
	public ShiftModel getCurrentShiftFromCache(String hotelId) {
		String key = hotelId + CacheKey.KEY_CACHE_CLASSNO;
		return (ShiftModel)simpleCache.get(key);
	}

	@Override
	public void setCurrentShiftToCache(String hotelId, ShiftModel shiftModel) {
		String key = hotelId + CacheKey.KEY_CACHE_CLASSNO;
		simpleCache.addCache(key, shiftModel);
	}
	
	@Override
	public IBaseDao<ShiftModel, Shift, String> getDao() {
		// TODO Auto-generated method stub
		return shiftDao;
	}

	@Override
	public ShiftModel getShiftDataFromAccount(List<AccountModel> accountModelList) {
		ShiftModel result = new ShiftModel();
		List<ShiftEmpModel> shiftEmpModelList = new ArrayList<>();

		for (AccountModel item:accountModelList ) {
			Byte accountType = item.getAccountType();
			Byte businessType = item.getBusinessType();
			Byte businessTypeDetail = item.getBusinessTypeDetail();
			BigDecimal money = item.getMoney();
			Byte accountStatus = item.getAccountStatus();
			String operatorId = item.getCreateUserId();

			if (accountType == null || businessType == null
					|| businessTypeDetail == null || money == null || accountStatus == null) {
				throw new BusinessException(AccountReturnCodeEnum.ACCOUNT_ATTRIBUTE_NULL_ERR.getCode(),
						AccountReturnCodeEnum.ACCOUNT_ATTRIBUTE_NULL_ERR.getDesc());
			}

			//应收
			if (accountType.equals(AccountTypeEnum.ACCOUNT_TYPE_YS.getValue())) {
				if (businessType.equals(BusinessTypeEnum.BUSINESS_TYPE_YSFF.getValue())
					|| businessType.equals(BusinessTypeEnum.BUSINESS_TYPE_JSFF.getValue())
						|| businessType.equals(BusinessTypeEnum.BUSINESS_TYPE_XTJF.getValue())
						|| businessType.equals(BusinessTypeEnum.BUSINESS_TYPE_NSFF.getValue())) {
					if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_QRZ.getValue())) {
						result.setYsFfQrz(money.add(result.getYsFfQrz()));
					}
					else if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_BRZ.getValue())) {
						result.setYsFfBrz(money.add(result.getYsFfBrz()));
					}
					else if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_ZDF.getValue())) {
						result.setYsFfZdf(money.add(result.getYsFfZdf()));
					}
					else if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_JCF.getValue())) {
						result.setYsFfJc(money.add(result.getYsFfJc()));
					}
					else if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_FWZK.getValue())) {
						result.setYsFfZk(money.add(result.getYsFfZk()));
					}
				}
				else if (businessType.equals(BusinessTypeEnum.BUSINESS_TYPE_XSD.getValue())) {
					if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_FF.getValue())) {
						result.setYsXsdFf(money.add(result.getYsXsdFf()));
					}
					else if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_KFB.getValue())) {
						result.setYsXsdKfb(money.add(result.getYsXsdKfb()));
					}
					else if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_QTB.getValue())) {
						result.setYsXsdQtb(money.add(result.getYsXsdQtb()));
					}
					else if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_CYB.getValue())) {
						result.setYsXsdCyb(money.add(result.getYsXsdCyb()));
					}
					else if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_HY.getValue())) {
						result.setYsXsdHy(money.add(result.getYsXsdHy()));
					}
					else if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_DS.getValue())) {
						result.setYsXsdDs(money.add(result.getYsXsdDs()));
					}
					else if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_FWF.getValue())) {
						result.setYsXsdFw(money.add(result.getYsXsdFw()));
					}
					else if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_QT.getValue())) {
						result.setYsXsdQt(money.add(result.getYsXsdQt()));
					}
				}
			}
			//实收
			else if (accountType.equals(AccountTypeEnum.ACCOUNT_TYPE_SS.getValue())) {
			    //先处理挂账
                if (businessType.equals(BusinessTypeEnum.BUSINESS_TYPE_DWZF.getValue())) {
                    result.setSsGzUnit(money.add(result.getSsGzUnit()));
                    continue;
                }
                else if (businessType.equals(BusinessTypeEnum.BUSINESS_TYPE_ZJZF.getValue())) {
                    result.setSsGzAgent(money.add(result.getSsGzAgent()));
                    continue;
                }
                else if (businessType.equals(BusinessTypeEnum.BUSINESS_TYPE_TRZF.getValue())) {
                    result.setSsGzOrder(money.add(result.getSsGzOrder()));
                    continue;
                }
                else if (businessType.equals(BusinessTypeEnum.BUSINESS_TYPE_GRDF.getValue())) {
                    result.setSsGzOrder(result.getSsGzOrder().subtract(money));
                    continue;
                }
                else if (businessType.equals(BusinessTypeEnum.BUSINESS_TYPE_MD.getValue())) {
                    result.setSsMdSum(money.add(result.getSsMdSum()));
                    continue;
                }
                else if (businessType.equals(BusinessTypeEnum.BUSINESS_TYPE_QT.getValue())) {
                    result.setSsQtSum(money.subtract(result.getSsQtSum()));
                    continue;
                }
                //缺少代金券和第三方应收@tobetter

                //只有退款时需要将金额变为负数
                if (businessType.equals(BusinessTypeEnum.BUSINESS_TYPE_TK.getValue())) {
                    money = BigDecimal.ZERO.subtract(money);
                }

                updateShiftOperatorEmp(shiftEmpModelList, item);

				//现金需要统计收款和退款
				if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_XJ.getValue())) {
					if (businessType.equals(BusinessTypeEnum.BUSINESS_TYPE_SK.getValue())) {
						result.setSsCashColl(money.add(result.getSsCashColl()));
					}
					else if (businessType.equals(BusinessTypeEnum.BUSINESS_TYPE_TK.getValue())) {
                        money = BigDecimal.ZERO.subtract(money);
						result.setSsCashOut(money.add(result.getSsCashOut()));
					}
					else {
						result.setSsCashColl(money.add(result.getSsCashColl()));
					}
					continue;
				}

				if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_SK.getValue())
                        || businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_ZZ.getValue())){
				    result.setSsBankSum(money.add(result.getSsBankSum()));
                }
                else if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_WX.getValue())) {
                    result.setSsWxSum(money.add(result.getSsWxSum()));
                }
                else if (businessTypeDetail.equals(BusinessTypeDetailEnum.BUSINESS_TYPE_DETAIL_ZFB.getValue())) {
                    result.setSsZfbSum(money.add(result.getSsZfbSum()));
                }
			}
		}

		//统计
		BigDecimal sum = BigDecimal.ZERO;

		//应收房费
		sum = result.getYsFfSum();
		sum = sum.add(result.getYsFfQrz());
		sum = sum.add(result.getYsFfBrz());
		sum = sum.add(result.getYsFfZdf());
		sum = sum.add(result.getYsFfJc());
		sum = sum.add(result.getYsFfZk());
		result.setYsFfSum(sum);

		//应收销售点
		sum = result.getYsXsdSum();
		sum = sum.add(result.getYsXsdFf());
		sum = sum.add(result.getYsXsdKfb());
		sum = sum.add(result.getYsXsdKfpc());
		sum = sum.add(result.getYsXsdQtb());
		sum = sum.add(result.getYsXsdCyb());
		sum = sum.add(result.getYsXsdHy());
		sum = sum.add(result.getYsXsdDs());
		sum = sum.add(result.getYsXsdFw());
		sum = sum.add(result.getYsXsdQt());
		result.setYsXsdSum(sum);

		sum = result.getYsSum();
		sum = sum.add(result.getYsFfSum());
        sum = sum.add(result.getYsXsdSum());
        result.setYsSum(sum);

		//实收
        sum = result.getSsCashSum();
        sum = sum.add(result.getSsCashColl());
        sum = sum.subtract(result.getSsCashOut());
        result.setSsCashSum(sum);

        sum = result.getSsGzSum();
        sum = sum.add(result.getSsGzUnit());
        sum = sum.add(result.getSsGzAgent());
        sum = sum.add(result.getSsGzOrder());
        sum = sum.add(result.getSsGzGroup());
        result.setSsGzSum(sum);

        sum = result.getSsSum();
        sum = sum.add(result.getSsCashSum());
        sum = sum.add(result.getSsBankSum());
        sum = sum.add(result.getSsWxSum());
        sum = sum.add(result.getSsZfbSum());
        sum = sum.add(result.getSsMemberSum());
        sum = sum.add(result.getSsGzSum());
        sum = sum.add(result.getSsMdSum());
        sum = sum.add(result.getSsDjqSum());
        sum = sum.add(result.getSsQtSum());
        sum = sum.add(result.getSs3rdSum());
        result.setSsSum(sum);

        //除现金、银行卡、微信和支付宝之外的其他收款
		sum = result.getSsSum();
		sum = sum.subtract(result.getSsCashSum());
		sum = sum.subtract(result.getSsBankSum());
		sum = sum.subtract(result.getSsWxSum());
		sum = sum.subtract(result.getSsZfbSum());
		result.setSsOtherSum(sum);

        //现金交班
        result.setShiftCash(result.getSsCashSum());
        result.setShiftBank(result.getSsBankSum());
        result.setShiftWx(result.getSsWxSum());
        result.setShiftZfb(result.getSsZfbSum());

        //总计
		sum = result.getToltalSum();
		sum = sum.add(result.getSsSum());
		sum = sum.subtract(result.getYsSum());

		return result;
	}
	
	/**
	 * 功能:重写save方法 <br/>
	 * 
	 * 重写：jiaokn <br/>
	 * 
	 * @Date ：2017年12月7日 下午5:23:40<br/>
	 * 
	 * @param shiftModel
	 * @return <br/>
	 * @see com.yuju.common.core.service.AbstractBaseService#save(java.lang.Object)
	 */
	@Override
	public int save(ShiftModel shiftModel){
		shiftModel.setId(Utils.getUUID());
		shiftModel.setGmtCreate(new Date());
		shiftModel.setGmtModified(new Date());
		return super.save(shiftModel);
	}

	@Override
	public ShiftModel getShift(String hotelId) {
		if (hotelId == null) {
			return null;
		}

		//获取当前班次Id
		ShiftModel currentShift = getCurrentShiftFromCache(hotelId);
		if (currentShift == null) {
			return null;
		}
		//获取当前班次号下的账务
		String classId = currentShift.getId();
		AccountModel accountModel = new AccountModel();
		accountModel.setClassId(classId);
		accountModel.setHotelId(hotelId);
		List<AccountModel> accountModelList = accountService.list(accountModel);

		//根据账务计算获得交班信息
		ShiftModel result = getShiftDataFromAccount(accountModelList);

		//补充班次信息
		result.setId(currentShift.getId());
		result.setHotelId(hotelId);
		result.setGroupId(currentShift.getGroupId());
		result.setBeginTime(currentShift.getBeginTime());
		result.setEndTime(new Date());
		result.setCode(currentShift.getCode());

		return result;
	}

	@Override
	public int addShift(String groupId, String hotelId, String empId,String empName, String hotelCode) {
		ShiftModel shiftModel = getShift(hotelId);

		shiftModel.setGmtModified(new Date());
		shiftModel.setEndTime(new Date());
		shiftModel.setShiftEmpId(empId);
		shiftModel.setShiftName(empName);
		shiftModel.setIsShift(StatusEnum.TRUE.getValue());

		try {
			//提交当前班次信息
			if (shiftModel.getShiftEmpModelList() != null) {
				for (ShiftEmpModel item:shiftModel.getShiftEmpModelList() ) {
					String id = Utils.getUUID();
					item.setId(id);
					shiftEmpService.save(item);
				}
			}

			shiftDao.updateSelective(shiftModel);

			//更新下一班次信息
			return this.initShift(groupId,hotelId,hotelCode);

		}
		catch (Exception e){
			throw new BusinessException(ShiftReturnCodeEnum.SHIFT_ADD_FAILURE.getCode(),
					ShiftReturnCodeEnum.SHIFT_ADD_FAILURE.getDesc());
		}
	}

	@Override
	public List<ShiftModel> getShiftIdFromDB(String hotelId) {
		return shiftDao.getCurrentShift(hotelId);
	}

	@Override
	public int initShift(String groupId, String hotelId, String hotelCode) {
		if (hotelId == null || hotelCode == null) {
			throw new BusinessException(ShiftReturnCodeEnum.SHIFT_HOTEL_INIT_FAILURE.getCode(),
					ShiftReturnCodeEnum.SHIFT_HOTEL_INIT_FAILURE.getDesc());
		}
		String id = Utils.getUUID();
		ShiftModel shiftModel = new ShiftModel();
		shiftModel.setId(id);
		shiftModel.setHotelId(hotelId);
		shiftModel.setGroupId(groupId);
		shiftModel.setBeginTime(new Date());
		shiftModel.setIsDeleted(StatusEnum.FALSE.getValue());
		shiftModel.setIsShift(StatusEnum.FALSE.getValue());
		String code = codeGenService.generate(groupId,hotelId,hotelCode,"CLASS_CODE");
		shiftModel.setCode(code);

		setCurrentShiftToCache(hotelId, shiftModel);

		return shiftDao.save(shiftModel);
	}

	@Override
	public List<ShiftModel> queryShiftInfo(ShiftModel shiftModel){
		shiftModel.setIsShift(StatusEnum.TRUE.getValue());
		return shiftDao.queryShiftInfo(shiftModel);
	}

	@Override
	public List<ShiftAccountModel> queryShiftAccountInfo(ShiftAccountModel shiftAccountModel){
		if (shiftAccountModel == null) {
			return null;
		}

		return shiftDao.queryShiftAccountInfo(shiftAccountModel);
	}

	@Override
	public String getCurrentClassId(String hotelId){
		ShiftModel shiftModel = getCurrentShiftFromCache(hotelId);
		if (shiftModel != null) {
			return shiftModel.getId();
		}
		else {
			return null;
		}
	}

	@Override
	public ShiftModel getPreviousShiftBaseInfo(String hotelId) {
		ShiftModel shiftModel = new ShiftModel();
		shiftModel.setHotelId(hotelId);
		shiftModel.setIsShift(StatusEnum.TRUE.getValue());

		List<ShiftModel> list = shiftDao.getShiftBaseInfo(shiftModel);
		if (list != null && list.size()>0) {
			return list.get(0);
		}
		else {
			return null;
		}
	}

	@Override
	public ShiftModel getCurrentShiftBaseInfo(String hotelId){
		return getCurrentShiftFromCache(hotelId);
	}

}
